package com.example.demo.api;

import com.example.demo.game.MatchRequest;
import com.example.demo.game.MatchResponse;
import com.example.demo.game.Matcher;
import com.example.demo.game.OnlineUserManager;
import com.example.demo.model.User;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.CloseStatus;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.socket.handler.TextWebSocketHandler;

/**
 * Created with IntelliJ IDEA.
 * Description:
 * User: Wukong
 * Date: 2023-04-24
 * Time: 19:47
 */
/**
 * 负责处理玩家的匹配请求、连接管理和异常处理
 * */
@Component
public class MatchAPI extends TextWebSocketHandler {
    //将 Java 对象转换为 JSON 字符串（序列化）。
    //将 JSON 字符串转换为 Java 对象（反序列化）
    private ObjectMapper objectMapper = new ObjectMapper();
        @Autowired
        private OnlineUserManager onlineUserManager;
        @Autowired
        private Matcher matcher;
        /**
         * 处理连接异常
         * */
        @Override
        public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception {
            // 1. 获取用户信息
            User user = (User) session.getAttributes().get("user");
            if (user == null) {
                return; // 用户未登录，忽略
            }

            // 2. 验证是否为当前活跃会话
            WebSocketSession existSession = onlineUserManager.getSessionFromGameHall(user.getUserId());
            if (existSession != session) {
                return; // 非活跃会话，忽略
            }

            // 3. 记录异常并清理状态
            System.out.println("匹配页面连接异常: " + user.getUserId() + ", message: " + exception.getMessage());
            onlineUserManager.exitGameHall(user.getUserId()); // 从游戏大厅移除
            matcher.remove(user); // 从匹配队列移除
        }
        /**
         * 处理连接关闭
         * */
        @Override
        public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
            // 1. 获取用户信息
            User user = (User) session.getAttributes().get("user");
            if (user == null) {
                return; // 用户未登录，忽略
            }

            // 2. 验证是否为当前活跃会话
            WebSocketSession existSession = onlineUserManager.getSessionFromGameHall(user.getUserId());
            if (existSession != session) {
                return; // 非活跃会话，忽略
            }

            // 3. 记录关闭并清理状态
            System.out.println("玩家离开匹配页面: " + user.getUserId());
            onlineUserManager.exitGameHall(user.getUserId()); // 从游戏大厅移除
            matcher.remove(user); // 从匹配队列移除
        }
        /**
         * 连接建立
         * */
    @Override
    public void afterConnectionEstablished(WebSocketSession session) throws Exception {
        // 1. 拿到用户信息.
        User user = (User) session.getAttributes().get("user");
        if (user == null) {
            // 拿不到用户的登录信息, 说明玩家未登录就进入游戏大厅了.
            // 则返回错误信息并关闭连接
            MatchResponse response = new MatchResponse();
            response.setOk(false);
            response.setReason("玩家尚未登录!");
            session.sendMessage(new TextMessage(objectMapper.writeValueAsString(response)));
            return;
        }
        // 2. 检查玩家的上线状态
        if (onlineUserManager.getSessionFromGameHall(user.getUserId()) != null
                || onlineUserManager.getSessionFromGameRoom(user.getUserId()) != null) {
            MatchResponse response = new MatchResponse();
            response.setOk(false);
            response.setReason("禁止多开游戏大厅页面!");
            session.sendMessage(new TextMessage(objectMapper.writeValueAsString(response)));
            return;
        }
        // 3. 设置玩家上线状态
        onlineUserManager.enterGameHall(user.getUserId(), session);
        System.out.println("玩家进入匹配页面: " + user.getUserId());
    }
    /**
     * 处理客户端发送的文本消息，解析为匹配请求
     * */
    @Override
    protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
        // 1. 拿到用户信息.
        User user = (User) session.getAttributes().get("user");
        if (user == null) {
            System.out.println("[onMessage] 玩家尚未登录!");
            return;
        }
        System.out.println("开始匹配: " + user.getUserId() + " message: " + message.toString());
        // 2. 解析读到的数据为 json 对象
        MatchRequest request = objectMapper.readValue(message.getPayload(), MatchRequest.class);
        MatchResponse response = new MatchResponse();
        if (request.getMessage().equals("startMatch")) {
            matcher.add(user);
            response.setMessage("startMatch");
        } else if (request.getMessage().equals("stopMatch")) {
            matcher.remove(user);
            response.setMessage("stopMatch");
        } else {
            // 匹配失败
            response.setOk(false);
            response.setReason("非法的匹配请求!");
        }
        session.sendMessage(new TextMessage(objectMapper.writeValueAsString(response)));
    }

}